﻿#include<iostream>
using std::cin;
using std::cout;
using std::endl;

//int main()
//{
//
//	int globalVar = 1;
//	static int staticGlobalVar = 1;
//	void Test()
//	{
//		static int staticVar = 1;
//		int localVar = 1;
//
//		int num1[10] = { 1, 2, 3, 4 };
//		char char2[] = "abcd";
//		char* pChar3 = "abcd";
//		int* ptr1 = (int*)malloc(sizeof(int) * 4);
//		int* ptr2 = (int*)calloc(4, sizeof(int));
//		int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);
//		free(ptr1);
//		free(ptr3);
//	}
//	return 0;
//}

////查看地址，分析存在区域
//int globalVar = 1;
//static int staticGlobalVar = 1;
//
//int main()
//{
//
//	static int staticVar = 1;
//	int localVar = 1;
//	const int a = 10;
//	cout << &globalVar << endl;
//	cout << &staticGlobalVar << endl;
//	cout << &staticVar << endl << endl;
//
//	cout << &localVar << endl;
//	cout << &a << endl;
//
//	//char* p = "hello";          //C++会报错，“hello”是const char*类型(const char{6])"hello",而p是char* 类型
//	const char* p = "hello";  //p存的是常量字符串的地址
//	cout << p << endl << endl;//无法这样打印p的地址，C++自动识别类型，是char*，
//	                          //会打印字符串hello
//	cout << (void*)p << endl; //需要强转类型或者使用C语言风格打印
//	cout << *p << endl;
//	cout << &p << endl;
//	cout << &("hello") << endl;
//
//
//	const int n = 10;
//	const int* b = &n;
//
//	cout << b << endl;        //打印的是n的地址
//	cout << &n << endl;       //打印的是n的地址
//	cout << (void*)b << endl; //打印的是n的地址
//	cout << *b << endl;
//	cout << &b << endl;
//
//	return 0;
//}
/////////////////////////////////////////////////////////////////////////////
////通过new和delete操作符进行动态内存管理
//
//int main()
//{
//	int* p1 = new int;     //动态创建一个int型对象
//	int* p2 = new int[10]; //动态创建10个int型对象，new[]数组
//	int* p3 = new int(10); //动态创建一个int型对象，并初始化为10
//	//int* p4 = new int[10](10);  //不能这么使用！
//	int* p5 = new int[10]{ 10 }; //C++11支持，这初始化的是第一个，其他默认为0
//
//	return 0;
//}

//int main()
//{
//	int* p1 = new int;     //动态创建一个int型对象
//	int* p2 = new int[10]; //动态创建10个int型对象，new[]数组
//	int* p3 = new int(10); //动态创建一个int型对象，并初始化为10
//	//int* p4 = new int[10](10);  //不能这么使用！
//	int* p5 = new int[10]{ 10 }; //C++11支持，这初始化的是第一个，其他默认为0
//
//	delete p1;      //要按照new创建的形式，对应delete的形式
//	delete[] p2;
//	delete p3;
//
//	delete[] p5;
//	return 0;
//}



//void Test()
//{
//	int* p1 = (int*)malloc(sizeof(int));
//	free(p1);
//
//	// 1.malloc/calloc/realloc的区别是什么？
//	int* p2 = (int*)calloc(4, sizeof(int));
//	int* p3 = (int*)realloc(p2, sizeof(int) * 10);
//
//	// 这里需要free(p2)吗？
//	free(p3);
//}
//
//class Test
//{
//public:
//	Test()
//		: _data(0)
//	{
//		cout << "Test():" << this << endl;
//	}
//	~Test()
//	{
//		cout << "~Test():" << this << endl;
//	}
//
//private:
//	int _data;
//};
//void Test2()
//{
//	// 申请单个Test类型的空间
//	Test* p1 = (Test*)malloc(sizeof(Test));
//	free(p1);
//
//	// 申请10个Test类型的空间
//	Test* p2 = (Test*)malloc(sizoef(Test) * 10);
//	free(p2);
//}
//void Test2()
//{
//	// 申请单个Test类型的对象
//	Test* p1 = new Test;
//	delete p1;
//
//	// 申请10个Test类型的对象
//	Test* p2 = new Test[10];
//	delete[] p2;
//}
//
///*
//operator new：该函数实际通过malloc来申请空间，当malloc申请空间成功时直接返回；申请空间失败，
//尝试执行空 间不足应对措施，如果改应对措施用户设置了，则继续申请，否则抛异常。
//*/
//void* __CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
//{
//	// try to allocate size bytes
//	void* p;
//	while ((p = malloc(size)) == 0)
//		if (_callnewh(size) == 0)
//		{
//			// report no memory
//			// 如果申请内存失败了，这里会抛出bad_alloc 类型异常
//			static const std::bad_alloc nomem;
//			_RAISE(nomem);
//		}
//	return (p);
//}
///*
//operator delete: 该函数最终是通过free来释放空间的
//*/
//void operator delete(void* pUserData) 
//{
//	_CrtMemBlockHeader* pHead;
//	RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
//	if (pUserData == NULL)
//		return;
//	_mlock(_HEAP_LOCK); /* block other threads */
//	__TRY
//		/* get a pointer to memory block header */
//		pHead = pHdr(pUserData);
//	/* verify block type */
//	_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
//	_free_dbg(pUserData, pHead->nBlockUse);
//	__FINALLY
//		_munlock(_HEAP_LOCK); /* release other threads */
//	__END_TRY_FINALLY
//		return;
//}
///*
//free的实现
//*/
//#define free(p)  _free_dbg(p, _NORMAL_BLOCK)
//
//
//
//struct ListNode
//{
//	ListNode* _next;
//	ListNode* _prev;
//	int _data;
//	void* operator new(size_t n)
//	{
//		void* p = nullptr;
//		p = allocator<ListNode>().allocate(1);
//		cout << "memory pool allocate" << endl;
//		return p;
//	}
//	void operator delete(void* p)
//	{
//		allocator<ListNode>().deallocate((ListNode*)p, 1);
//		cout << "memory pool deallocate" << endl;
//	}
//};
//class List
//{
//public:
//	List()
//	{
//		_head = new ListNode;
//		_head->_next = _head;
//		_head->_prev = _head;
//	}
//	~List()
//	{
//		ListNode* cur = _head->_next;
//		while (cur != _head)
//		{
//			ListNode* next = cur->_next;
//			delete cur;
//			cur = next;
//		}
//		delete _head;
//		_head = nullptr;
//	}
//private:
//	ListNode* _head;
//};
//int main()
//{
//	List l;
//	return 0;
//}
//
//class Test
//{
//public:
//	Test()
//		: _data(0)
//	{
//		cout << "Test():" << this << endl;
//	}
//	~Test()
//	{
//		cout << "~Test():" << this << endl;
//	}
//
//private:
//	int _data;
//};
//void Test()
//{
//	// pt现在指向的只不过是与Test对象相同大小的一段空间，还不能算是一个对象，因为构造函数没有执行
//	Test* pt = (Test*)malloc(sizeof(Test));
//
//	new(pt) Test; // 注意：如果Test类的构造函数有参数时，此处需要传参
//}

////对于内置类型而言，使用malloc和new，只是用法形式不同，
////区别在于自定义类型，malloc只开辟空间，new开辟空间+初始化
//
//#include<assert.h>
//#include<stdlib.h>
//////C语言中，malloc只开空间，不初始化
////struct ListNode
////{
////	ListNode* _next;
////	int _val;
////};
////struct ListNode* BuyListNode(int x)
////{
////	struct ListNode* node = (struct ListNode*)malloc(sizeof(struct ListNode));
////	assert(node);
////	node->_next = NULL;
////	node->_val = x;
////	return node;
////}
////int main()
////{
////	ListNode* n1 = BuyListNode(1); //C语言中，malloc只开空间，不初始化
////	return 0;
////}
//
////C++中，new开辟空间+调用构造函数初始化
//struct ListNode
//{
//	ListNode* _next;
//	int _val;
//	//C++中，new会调用构造函数初始化
//	ListNode(int val=0)
//		: _next(nullptr)
//		, _val(val)
//	{}
//};
////在c语言中，因为malloc只开辟空间，不初始化
////写BuyListNode()是为了开辟空间+初始化
//struct ListNode* BuyListNode(int x)
//{
//	struct ListNode* node = (struct ListNode*)malloc(sizeof(struct ListNode));
//	assert(node);
//	node->_next = NULL;
//	node->_val = x;
//	return node;
//}
//int main()
//{
//	ListNode* n1 = BuyListNode(1); //C语言中，malloc只开空间，不初始化，
//									 //自定义函数BuyListNode()是为了开辟空间+初始化
//	//ListNode* n1=(struct ListNode*)malloc(sizeof(struct ListNode)); //C语言，malloc只开辟空间
//	assert(n1);
//
//	ListNode* p1 = new ListNode;   //C++中，new开辟空间+调用构造函数初始化
//	ListNode* p2 = new ListNode(10);   
//	ListNode* p3 = new ListNode(20);
//	ListNode* p4 = new ListNode(30);
//
//	return 0; 
//}

//#include<cassert>
//class Stack
//{
//public:
//	Stack(int capacity = 10)
//		:_a(new int[capacity])
//		,_capacity(capacity)
//		,_top(0)
//	{}
//	~Stack()
//	{
//		delete[] _a;
//		_capacity = 0;
//		_top = 0;
//	}
//private:
//	int* _a;
//	int _top;
//	int _capacity;
//};
//
//int main()
//{
//	//Stack st;
//	//C语言中，malloc只开辟空间，不初始化
//	Stack* c1 = (Stack*)malloc(sizeof(Stack));
//	assert(c1);
//	//c1->Stack(); error  //构造函数不能显式调用，这种方式在这里无法初始化了，无法访问私有成员。
//	           
//	//C++中，new开辟空间+初始化
//	Stack* ps1 = new Stack;
//
//	free(c1);
//	delete ps1;
//	return 0;
//}

////C++用栈实队列,部分框架讲解new和delete
//#include<cassert>
//class Stack
//{
//public:
//	Stack(int capacity = 10)
//		:_a(new int[capacity])
//		, _capacity(capacity)
//		, _top(0)
//	{
//		cout << "Stack(int capacity = 10)" << endl;
//	}
//	~Stack()
//	{	
//		delete[] _a;
//		_capacity = 0;
//		_top = 0;
//		cout << "~Stack()" << endl;
//	}
//private:
//	int* _a;
//	int _top;
//	int _capacity;
//};
////队列类，没写构造函数、没写析构函数
////调用默认构造函数和默认析构函数
//class MyQueue
//{
//private:
//	//自定义类型
//	Stack _pushST;
//	Stack _popST;
//};
//int main()
//{
//	MyQueue* obj = new MyQueue;
//	delete obj;
//	return 0;
//}

//int main()
//{
//	//先消耗内存
//	void* p0 = malloc(1024 * 1024 * 1024);   //模拟开设1G的内存  即十亿个字节
//	cout << p0 << endl;
//
//	//在C语言中，malloc创建后需要assert，因为malloc失败，会返回空指针
//	void* p1 = malloc(1024 * 1024 * 1024);   //模拟开设1G的内存  即十亿个字节
//	cout << p1 << endl;
//
//	//在C++ 中，new失败就会抛异常。 
//	void* p2 = new char[1024 * 1024 * 1024];  //模拟开设1G的内存  即十亿个字节
//	cout << p2 << endl;
//	return 0;
//}

//using namespace std;
//int main()
//{
//	//先消耗内存
//	void* p0 = malloc(1024 * 1024 * 1024);   //模拟开设1G的内存  即十亿个字节
//	cout << p0 <<endl<< endl;
//
//	//在C语言中，malloc创建后需要assert，因为malloc失败，会返回空指针
//	void* p1 = malloc(1024 * 1024 * 1024);   //模拟开设1G的内存  即十亿个字节
//	cout << p1 << endl << endl;
//
//	//在C++ 中，new失败就会抛异常。 
//	try
//	{
//		void* p2 = new char[1024 * 1024 * 1024];  //模拟开设1G的内存  即十亿个字节
//		cout << p2 <<endl;
//	}
//	catch (const exception& e)
//	{
//		cout << e.what() <<endl<< endl;
//	}
//	return 0;
//}

//#include<iostream>
//#include<cstdlib>
//#include<cassert>
//using namespace std;
//
////C++用栈实队列,部分框架讲解new和delete
//#include<cassert>
//class Stack
//{
//public:
//	Stack(int capacity = 10)
//		:_a(new int[capacity])
//		, _capacity(capacity)
//		, _top(0)
//	{
//		cout << "Stack(int capacity = 10)" << endl;
//	}
//	~Stack()
//	{
//		delete[] _a;
//		_capacity = 0;
//		_top = 0;
//		cout << "~Stack()" << endl;
//	}
//private:
//	int* _a;
//	int _top;
//	int _capacity;
//};
////异常一般在main外部捕获
//void func()
//{
//	Stack* c1 = (Stack*)malloc(sizeof(Stack)); //C语言malloc
//    assert(c1);
//	
//    Stack* ps1 = new Stack;                    //C++new
//
//	free(c1);
//	delete ps1;
//	//先消耗内存
//	void* p0 = malloc(1024 * 1024 * 1024);   //模拟开设1G的内存  即十亿个字节
//	if (p0 == NULL)
//	{
//		cout << p0 << endl << endl;
//	}
//	
//	//在C语言中，malloc创建后需要assert，因为malloc失败，会返回空指针
//	void* p1 = malloc(1024 * 1024 * 1024);   //模拟开设1G的内存  即十亿个字节
//	if (p1 == NULL)
//	{
//		cout << p1 << endl << endl;
//	}
//	
//	//在C++ 中，new失败就会抛异常。 
//	void* p2 = new char[1024 * 1024 * 1024];  //模拟开设1G的内存  即十亿个字节
//	cout << p2 << endl;
//}
//int main()
//{
//	//在C++ 中，new失败就会抛异常。 
//	try
//	{
//		func();
//	}
//	catch (const exception& e)
//	{
//		cout << e.what() << endl << endl;
//	}
//	return 0;
//}


#include<iostream>
#include<cstdlib>
#include<cassert>
using namespace std;

////C++用栈实队列,部分框架讲解new和delete
//#include<cassert>
//class Stack
//{
//public:
//	Stack(int capacity = 10)
//		:_a(new int[capacity])
//		, _capacity(capacity)
//		, _top(0)
//	{
//		cout << "Stack(int capacity = 10)" << endl;
//	}
//	~Stack()
//	{
//		delete[] _a;
//		_capacity = 0;
//		_top = 0;
//		cout << "~Stack()" << endl;
//	}
//private:
//	int* _a;
//	int _top;
//	int _capacity;
//};
//int main()
//{
//	//malloc
//	Stack* ps1 = (Stack*)malloc(sizeof(Stack));
//	assert(ps1);
//	free(ps1);
//	//operator new
//	Stack* ps2 = (Stack*)operator new(sizeof(Stack));
//	operator delete(ps2);
//	//new
//	Stack* ps3 = new Stack;
//							//call operator new
//							//call Stack构造函数
//	delete ps3;
//	return 0;
//}

//struct ListNode
//{
//	ListNode* _next;
//	ListNode* _prev;
//	int _data;
//
//	ListNode(int data=0)
//		:_next(nullptr)
//		,_prev(nullptr)
//		,_data(data)
//	{
//		cout << "ListNode()" << endl;
//	}
//	//ListNode专属的operator
//	void* operator new(size_t n)
//	{
//		void* p = nullptr;
//		p = allocator<ListNode>().allocate(1);
//		cout << "memory pool allocate" << endl;
//		return p;
//	}
//	void operator delete(void* p)
//	{
//		allocator<ListNode>().deallocate((ListNode*)p, 1);
//		cout << "memory pool deallocate" << endl;
//	}
//};
//class List
//{
//public:
//	List()
//	{
//		_head = new ListNode;
//		_head->_next = _head;
//		_head->_prev = _head;
//	}
//	void PushBack(int val)
//	{
//		ListNode* newnode = new ListNode;
//		ListNode* tail = _head->_prev;
//		tail->_prev = newnode;
//		newnode->_next = _head;
//		_head->_prev = newnode;
//	}
//	void Clear()
//	{
//		ListNode* cur = _head->_next;
//		while (cur != _head)
//		{
//			ListNode* next = cur->_next;
//			delete cur;
//			cur = next;
//		}
//		_head->_next = _head;
//		_head->_prev = _head;
//	}
//	~List()
//	{
//		Clear();
//		delete _head;
//		_head = nullptr;
//	}
//private:
//	ListNode* _head;
//};
//int main()
//{
//	List l;
//	//多次存入入数据、清除数据
//	//多次向堆申请开辟空间，释放空间
//	int n;
//	cin >> n;
//	for (int i = 0; i < n; ++i)
//	{
//		l.PushBack(i);
//	}
//	l.Clear();
//	cout << endl << endl;
//	cin >> n;
//	for (int i = 0; i < n; ++i)
//	{
//		l.PushBack(i);
//	}
//	return 0;
//}



//class Test
//{
//public:
//	Test()
//		: _data(0)
//	{
//		cout << "Test():" << this << endl;
//	}
//	~Test()
//	{
//		cout << "~Test():" << this << endl;
//	}
//
//private:
//	int _data;
//};
//void Test()
//{
//	// pt现在指向的只不过是与Test对象相同大小的一段空间，还不能算是一个对象，因为构造函数没有执行
//	Test* pt = (Test*)malloc(sizeof(Test));
//
//	new(pt) Test; // 注意：如果Test类的构造函数有参数时，此处需要传参
//}


////C++用栈实队列,部分框架讲解new和delete
//#include<cassert>
//class Stack
//{
//public:
//	Stack(int capacity = 10)
//		:_a(new int[capacity])
//		, _capacity(capacity)
//		, _top(0)
//	{
//		cout << "Stack(int capacity = 10)" << endl;
//	}
//	~Stack()
//	{
//		delete[] _a;
//		_capacity = 0;
//		_top = 0;
//		cout << "~Stack()" << endl;
//	}
//private:
//	int* _a;
//	int _top;
//	int _capacity;
//};
//int main()
//{
//
//	////operator new
//	//Stack* ps2 = (Stack*)operator new(sizeof(Stack));
//	////ps2->_top=0;  不能这样调用，无法访问私有成员
//	//				//也不能显式调用构造函数，因为是自动调用的
//	//operator delete(ps2);
//	
//	//定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象
//	Stack* obj= (Stack*)operator new(sizeof(Stack));
//	new(obj)Stack(4);  //等价于Stack* obj=new Stack(4);
//
//
//	return 0;
//}


//////////////////////////////////////////////////////
//内存泄漏
//内存泄漏是指针丢了，还是内存丢了？是指针

//int main()
//{
//	//普通的内存泄漏
//	void* p = new char[1024 * 1024 * 1024];
//	//特殊的内存泄漏，后果很严重
//	return 0;
//}

// 将程序编译成x64的进程，运行下面的程序试试？
#include <iostream>
using namespace std;
int main()
{
	void* p = new char[0xfffffffful];
	cout << "new:" << p << endl;
	return 0;
}
